﻿
using AutoMapper;
using IoTAdapter.BaseCore.Enums;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using Redbus.Interfaces;
using SqlSugar;
using System.ComponentModel;
using System.Reflection;
using Warehouse.Services.Repository;
using WCS.Entities;
using WCS.Entities.Api;
using WCS.ViewModels;

namespace WCS.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DeviceController : ControllerBase
    {

        #region  Filed

        private readonly ILogger<DeviceController> logger;
        private readonly Repository<Device> deviceRepository;
        private readonly IMapper mapper;
        //private readonly IEventBus eventBus;
        public DeviceController(
            ILogger<DeviceController> logger,
            Repository<Device> deviceRepository
            //IEventBus eventBus
            )
        {
            this.logger = logger;
            this.deviceRepository = deviceRepository;
            //this.eventBus = eventBus;
        }

        #endregion

        #region 创建

        /// <summary>
        /// 创建设备
        /// </summary>
        /// <param name="mapper"></param>
        /// <param name="deviceDto">设备信息</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult<ApiResult>> Create([FromServices] IMapper mapper, DeviceDto deviceDto)
        {

            var device = mapper.Map<Device>(deviceDto);
            var isok = await deviceRepository.AddAsync(device);
            if (isok)
            {
                //eventBus.PublishModelChange("Device", Operation.Add, deviceDto);
                return ApiResultHelp.Success(device);
            }
            else
                return ApiResultHelp.Error("添加失败，服务器发生错误");

        }

        /// <summary>
        /// 导入设备信息
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ApiResult> Import([FromServices] IMapper mapper, DeviceDto[] tag)
        {
            try
            {
                var datas = mapper.Map<List<Device>>(tag);
                foreach (var item in datas)
                {
                    if (await deviceRepository.IsExistAsync(x => x.Id == item.Id))
                    {
                        //eventBus.PublishModelChange("Device", Operation.Update, item);
                        await deviceRepository.UpdateAsync(item);
                    }
                    else
                    {
                        //eventBus.PublishModelChange("Device", Operation.Add, item);
                        await deviceRepository.AddAsync(item);
                    }
                }
                return ApiResultHelp.Success("导入成功!");
            }
            catch (Exception ex)
            {
                return ApiResultHelp.Error("导入失败!" + ex.Message);
            }
        }

        #endregion

        #region 更新

        /// <summary>
        /// 更新设备信
        /// </summary>
        /// <param name="iMapper"></param>
        /// <param name="id">设备的Id</param>
        /// <param name="deviceDto">新设备的信息</param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<ApiResult> Update([FromServices] IMapper mapper, string id, DeviceDto deviceDto)
        {
            if (!deviceRepository.IsExist(x => x.Id == id))
                return ApiResultHelp.Error("没有找到该设备");
            var device = mapper.Map<Device>(deviceDto);
            if (await deviceRepository.UpdateAsync(device))
            {
                //eventBus.PublishModelChange("Device", Operation.Update, device);
                return ApiResultHelp.Success(device);
            }
            else
                return ApiResultHelp.Error("修改失败");
        }

        /// <summary>
        /// 启用/禁用
        /// </summary>
        /// <returns></returns>
        [HttpPatch("{id}/{enable}")]
        public async Task<ActionResult<ApiResult>> Enable(string id, bool enable)
        {
            if (!deviceRepository.IsExist(x => x.Id == id))
                return ApiResultHelp.Error("没有找到该设备");
            var device = await deviceRepository.FindAsync(id);
            device.Enable = enable;
            if (await deviceRepository.UpdateAsync(device))
            {
                //eventBus.PublishModelChange("Device", Operation.Update, device);
                return ApiResultHelp.Success(device);
            }
            else
                return ApiResultHelp.Error("修改失败");
        }

        #endregion

        #region 删除

        /// <summary>
        /// 删除设备通过Id
        /// </summary>
        /// <param name="deviceId">设备的Id</param>
        /// <returns></returns>
        [HttpDelete("{deviceId}")]
        public async Task<ActionResult<ApiResult>> Delete([FromServices] Repository<TransferPort> portRepository, string deviceId)
        {
            if (await deviceRepository.DeleteByIdAsync(deviceId))
            {
                if (await portRepository.IsExistAsync(p => p.DeviceId == deviceId))
                {
                    var port = await portRepository.FindAsync(p => p.DeviceId == deviceId);
                    await portRepository.DeleteAsync(port);
                }
                //eventBus.PublishModelChange("Device", Operation.Delete, deviceId);

                return ApiResultHelp.Success(deviceId);
            }
            else
                return ApiResultHelp.Error("删除失败");
        }

        /// <summary>
        /// 批量删除设备
        /// </summary>
        /// <param name="ids">要删除的设备Ids</param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ActionResult<ApiResult>> DeleteByIds([FromServices] Repository<TransferPort> portRepository, string[] ids)
        {
            if (await deviceRepository.DeleteByIdsAsync(ids))
            {
                foreach (var deviceId in ids)
                {
                    if (await portRepository.IsExistAsync(p => p.DeviceId == deviceId))
                    {
                        var port = await portRepository.FindAsync(p => p.DeviceId == deviceId);
                        await portRepository.DeleteAsync(port);
                    }
                }
                //eventBus.PublishModelChange("Device", Operation.Delete, ids);
                return ApiResultHelp.Success(ids);
            }
            else
                return ApiResultHelp.Error("删除失败");
        }

        #endregion

        #region 查找 

        /// <summary>
        /// 查找设备
        /// </summary>
        /// <param name="iMapper"></param>
        /// <param name="page">当前页码</param>
        /// <param name="limit">每页大小</param>
        /// <param name="query">筛选条件</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetDevicesByPage([FromServices] IMapper iMapper, int page, int limit, [FromQuery] string query)
        {
            RefAsync<int> total = 0;
            try
            {
                if (query != null)
                {
                    JObject jobject = JObject.Parse(query);
                    var models = new List<IConditionalModel>();
                    foreach (var key in jobject.Properties())
                    {
                        if (string.IsNullOrEmpty(key.Value.ToString()))
                            continue;
                        if (key.Name == "type")
                        {
                            if (key.Value.ToString() != "None")
                            {
                                int index = (int)(EthernetDeviceVersion)Enum.Parse(typeof(EthernetDeviceVersion), key.Value.ToString());
                                models.Add(new ConditionalModel()
                                { FieldName = key.Name, FieldValue = index.ToString(), ConditionalType = ConditionalType.Like });
                            }
                        }
                        else
                        {
                            models.Add(new ConditionalModel()
                            { FieldName = key.Name, FieldValue = key.Value.ToString(), ConditionalType = ConditionalType.Like });
                        }
                    }
                    var devices = await deviceRepository.QueryAsync(models, page, limit, total);
                    List<DeviceDto> deviceDtos = iMapper.Map<List<DeviceDto>>(devices);
                    return ApiResultHelp.Success(new { list = deviceDtos, total = total.Value });
                }
                else
                {
                    var devices = await deviceRepository.QueryAsync(page, limit, total);
                    List<DeviceDto> deviceDtos = iMapper.Map<List<DeviceDto>>(devices);
                    return ApiResultHelp.Success(new { list = deviceDtos, total = total.Value });
                }
            }
            catch (Exception ex)
            {
                return ApiResultHelp.Error($"查询出错:{ex.Message}");
            }
        }

        /// <summary>
        /// 是否存在设备
        /// </summary>
        /// <returns></returns>
        [HttpGet()]
        public async Task<ActionResult<ApiResult>> Check([FromQuery] string query)
        {

            JObject jobject = JObject.Parse(query);
            try
            {
                List<IConditionalModel> models = new List<IConditionalModel>();

                foreach (var key in jobject.Properties())
                {
                    if (key.Name.ToString().ToLower() == "id" && jobject.Count > 1)
                    {
                        continue;
                    }
                    models.Add(new ConditionalModel()
                    {
                        FieldName = key.Name,
                        FieldValue = key.Value.ToString(),
                        ConditionalType = ConditionalType.Equal
                    });
                }
                var devices = await deviceRepository.Context.Queryable<Device>().Where(models).ToListAsync();
                if (jobject.ContainsKey("id") && jobject.Count > 1)
                {
                    var count = devices.Count(x => x.Id != jobject["id"]!.ToString());
                    return ApiResultHelp.Success(count);
                }
                return ApiResultHelp.Success(devices.Count);
            }
            catch (Exception e)
            {
                return ApiResultHelp.Error("查找设备出错" + e.Message);
            }
        }

        /// <summary>
        /// 查找相关设备类型
        /// </summary>
        /// <param name="type">设备类型</param>
        /// <returns></returns>
        [HttpGet("{type?}")]
        public async Task<ApiResult> GetDeviceTypes(string? type)
        {
            Dictionary<string, string> types = new();

            return await Task.Run(() =>
            {
                foreach (EthernetDeviceVersion value in Enum.GetValues(typeof(EthernetDeviceVersion)))
                {
                    var fi = value.GetType().GetField(value.ToString());
                    var attributes = fi?.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];
                    types.Add(attributes?[0].Description, Enum.GetName(value));
                }
                if (!string.IsNullOrEmpty(type))
                {
                    if (type.ToLower().Contains("siemens"))
                    {
                        types = types.Where(x => x.Key.Contains("Siemens")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }
                    else if (type.ToLower().Contains("modbus"))
                    {
                        types = types.Where(x => x.Key.Contains("Modbus")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }
                    else if (type.ToLower().Contains("mitsubishi"))
                    {
                        types = types.Where(x => x.Key.Contains("三菱")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }
                    else if (type.ToLower().Contains("omron"))
                    {
                        types = types.Where(x => x.Key.Contains("OmronFins")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }
                    else if (type.ToLower().Contains("allenbradley"))
                    {
                        types = types.Where(x => x.Key.Contains("AllenBradley")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }

                    else
                    {
                        types = types.Where(x => x.Key.Contains("CallButton") || x.Key.Contains("TcpClient")).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); ;
                    }
                }
                return ApiResultHelp.Success(types.ToArray());

            });
        }

        /// <summary>
        /// 查找所有设备的iP和id
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ApiResult> GetDeviceInfos()
        {
            try
            {
                var info = await deviceRepository.Context.Queryable<Device>().ToDictionaryAsync(x => x.IP, x => x.Id);
                return ApiResultHelp.Success(info.ToArray());
            }
            catch (Exception ex)
            {
                return ApiResultHelp.Error($"异常抛出，异常信息：{ex.Message}");
            }
        }

        #endregion
    }
}
